# -*- coding: utf-8 -*-
# =============================================================================
#     FileName:
#         Desc:
#       Author: GGA
#        Email:
#     HomePage:
#      Version: 1.0.1
#   LastChange: 2020-12-20
#      History:
# =============================================================================
import os
import sys
import subprocess
import logging
import re
import datetime

import fire

from utils.logger_helper import LoggerHelper
from common_config import CommonConfig
from mysql_binlog_parser import MySQLBinlogParser

logger = LoggerHelper.get_logger()


class BinlogTableActionChecker(object):

    @classmethod
    def check_binlog(cls, binlog_path):
        if not os.path.exists(binlog_path):
            logger.warning("指定的binlog存在")
            return False
        logger.info("开始解析binlog: {}".format(binlog_path))
        cmd_temp = """ {mysqlbinlog_exe} -v --base64-output=DECODE-ROWS '{binlog_path}' | egrep '^### INSERT|^### UPDATE|^### DELETE|server id' """
        cmd = cmd_temp.format(
            mysqlbinlog_exe=CommonConfig.MYSQLBINLOG_EXE,
            binlog_path=binlog_path
        )
        parse_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        current_line_num = 0
        current_time = None
        table_action_dict = dict()
        while True:
            file_bytes = parse_process.stdout.readline()
            if not file_bytes:
                break
            current_line = file_bytes.decode().strip()
            current_line_num += 1
            if current_line_num % 10000 == 0:
                logger.info("当前处理到第{}行".format(current_line_num))
            table_name = MySQLBinlogParser.parse_table_name_line(current_line)
            if table_name is not None:
                table_action = current_line.replace("#", "").strip()
                if table_action not in table_action_dict.keys():
                    table_action_dict[table_action] = 0
                table_action_dict[table_action] += 1
                continue
        logger.info("解析binlog完成")
        logger.info("*" * 40)
        ops_items = sorted(table_action_dict.items(), key=lambda x: x[1], reverse=True)
        print("{:10} : {}".format("exec_count", "table_action"))
        for ops_item in ops_items:
            print("{:10} : {}".format(ops_item[1], ops_item[0]))
        logger.info("*" * 40)


def check_ops(binlog_path):
    """

    :param binlog_path: 要解析BINLOG文件路径
    :return:
    """
    LoggerHelper.init_logger()
    BinlogTableActionChecker.check_binlog(binlog_path=binlog_path)


if __name__ == '__main__':
    fire.Fire(check_ops)
